(function(angular) {
	'use strict';
	angular.module('fs.waf').factory('payCodeService', payCodeService);
	payCodeService.$inject = [ '$q', 'loggerFactory', 'commonService', 'ajaxServiceFactory', 'modalService', 'gridService' ];
	function payCodeService($q, loggerFactory, commonService, ajaxServiceFactory, modalService, gridService) {
		var log = loggerFactory.getLogger("payCodeService"), ajaxService = ajaxServiceFactory.buildAjaxService({
			dropDownDataOptions : {
				url : 'do/cda/payCode/dropDownDataOptions',
				method : 'get'
			}
		});
		function dropDownDataOptions() {
			var defer = $q.defer();
			ajaxService.dropDownDataOptions().then(function(response) {
				var options = {};
				if (response.data) {
					angular.forEach(response.data, function(value, key) {
						var tempValue = {};
						tempValue = value;
						options[key] = tempValue;
					});
				}
				defer.resolve(options);
			});
			return defer.promise;
		}
		function firstStrToUpCase(str) {
		    str = str.toLowerCase();
		    var reg = /\b(\w)|\s(\w)/g;
		    return str.replace(reg,
		    function(m) {
		        return m.toUpperCase();
		    });
		}
		function initDropDownDataOptions($scope, ctrl) {
			var defer = $q.defer();
			dropDownDataOptions().then(function(response) {
				ctrl.yesOrNoOptions = response.yesOrNoOptions;
				ctrl.usedForOptions = response.usedForOptions;
				ctrl.ccyOptions = response.ccyOptions;
				ctrl.feeCodeOptions = response.feeCodeOptions;
				ctrl.crTemplateCodeOptions = response.templateCodeOptions;
				ctrl.drTemplateCodeOptions = response.templateCodeOptions;
				defer.resolve();
			}, angular.noop);
			return defer.promise;
		}
		function initGeneral($scope, ctrl, listFlag) {
			var crdrs = ['cr', 'dr'];
			if(!listFlag) {
				ctrl.reconcileDisableFlag = true;
				ctrl.excludeDisableFlag = true;
				ctrl.feeCodeShowFlag = true;
				//for payCodeCatOptions
				ctrl.payCodeCatOptions = ctrl.payCode.payCodeCatOptions;
				
				var payCodeCats = ctrl.payCode.payCodeCats;
				//for crdrOptions
				ctrl.crdrOptions = [];
				function resetData (crdr, payCodeCatObj) {
					ctrl[crdr + "DeliveryTypeOptions"] = {};
					ctrl[crdr + "DeliveryTypeOptions"].callback = {};
					ctrl[crdr + "DeliveryTypeOptions"].callback.changed = "vm." + crdr + "DeliveryTypeChanged";
					ctrl[crdr + "AdviceFlag"] = (payCodeCatObj && "Y" == payCodeCatObj[crdr + "AdviceFlag"]) ? true : false;
					ctrl.payCode[crdr +"AdviceFlag"] = (payCodeCatObj) ? payCodeCatObj[crdr + "AdviceFlag"] || 'N' : 'N';
					ctrl[crdr + "DeliveryInfoSwiftFlag"] = false;
					ctrl[crdr + "DeliveryInfoEmailFlag"] = false;
					ctrl[crdr + "DeliveryInfoFaxFlag"] = false;
					ctrl[crdr + "DeliveryInfoMailFlag"] = false;
					ctrl[crdr + "CheckFlag"] = false;
					ctrl[crdr + "InvoiceFlag"] = false;
					ctrl[crdr + "TemplateInfoFlag"] = false;
				}
				//for crDeliveryTypeOptions
				angular.forEach(crdrs, function(crdr, index) {
					resetData(crdr);
				});
				ctrl.creditTabFlag = false;
				ctrl.crdrChanged = function(value) {
					ctrl.creditTabFlag = false;
					ctrl.debitTabFlag = false;
					if(ctrl.crAdviceFlag && ("C" == ctrl.payCode.usedFor || "B" == ctrl.payCode.usedFor)) {
						ctrl.activeIndex = 0;
						ctrl.creditTabFlag = true;
					}
					if(ctrl.drAdviceFlag && ("D" == ctrl.payCode.usedFor  || "B" == ctrl.payCode.usedFor)) {
						ctrl.activeIndex = 1;
						ctrl.debitTabFlag = true;
					}
					if(ctrl.crAdviceFlag && ctrl.drAdviceFlag && "B" == ctrl.payCode.usedFor) {
						ctrl.activeIndex = 0;
						ctrl.creditTabFlag = true;
						ctrl.debitTabFlag = true;
					}
				};
				function setReconcileDisableFlag(paycodeCat) {
					//I for Invoce, K for Check.
					ctrl.reconcileDisableFlag = ("INVOICE" != paycodeCat.split("-")[1]);
					if(ctrl.reconcileDisableFlag){
						ctrl.payCode.reconcileFlag ='N';
					}
				}
				function setExcludeDisableFlag(paycodeCat) {
					//G for GL Acct.
					ctrl.excludeDisableFlag = ("GL" != paycodeCat.split("-")[1]);
					if(ctrl.excludeDisableFlag){
						ctrl.payCode.excludeFlag ='N';
					}
				}
				function seFeeCodeShowFlag(paycodeCat) {
					//W for Swift
					ctrl.feeCodeShowFlag = true;
				}
				function seDynaParmShowOrHidden(paycodeCat) {
					var payCodeCatMgr, payCodeCatOptions = ctrl.payCode.payCodeCatOptions;
					angular.forEach(payCodeCatOptions, function(payCodeCatOption, index) {
						if(paycodeCat == payCodeCatOption.value) {
							payCodeCatMgr = payCodeCatOption.extProperty;
						}
					});
					
					var gridConfigs = ctrl.layoutConfig.formConfigs.general.gridConfigs;
					angular.forEach(gridConfigs, function(gridConfig, index) {
						//subCategory  like PAYCATMGR-xxx  or PAYCAT-xxx
						if(gridConfig.dynamicParameter) {
							if(!paycodeCat) {
								gridConfig.active = false;
							} else if(gridConfig.dynamicParameter.subCategory.indexOf("PAYCATMGR-") == 0 ) {
								if(payCodeCatMgr == gridConfig.dynamicParameter.subCategory.substring("PAYCATMGR-".length, gridConfig.dynamicParameter.subCategory.length)) {
									gridConfig.active = true;
								} else {
									gridConfig.active = false;
								}
							} else if(gridConfig.dynamicParameter.subCategory.indexOf("PAYCAT-") == 0 ) {
								if(paycodeCat.split("-")[1] == gridConfig.dynamicParameter.subCategory.substring("PAYCAT-".length, gridConfig.dynamicParameter.subCategory.length)) {
									gridConfig.active = true;
								} else {
									gridConfig.active = false;
								}
							}
						}
					});
				}
				
				function seAdViceData(payCodeCatObj, crdr) {
					//I for Invoce, K for Check.
					if("INVOICE" == payCodeCatObj.paycodeCat.split("-")[1] || "CHECK" == payCodeCatObj.paycodeCat.split("-")[1]) {
						ctrl.payCode[crdr + "TemplateCategory"] = payCodeCatObj[crdr + "TemplateCategory"];
						ctrl[crdr + "TemplateInfoFlag"] = true;
						ctrl[crdr + firstStrToUpCase(payCodeCatObj.paycodeCatName) + "Flag"] = true;
						
					}
				}
				var oldPayCode = angular.copy(ctrl.payCode);
				ctrl.payCodeCatChanged = function() {
					var payCodeCat = ctrl.payCode.paycodeCat;
					seDynaParmShowOrHidden(payCodeCat);
					angular.forEach(payCodeCats, function(payCodeCatObj, index) {
						if(payCodeCat == payCodeCats[index].paycodeCat) {
							ctrl.crdrOptions = payCodeCatObj.crDrOptions;
							if(payCodeCat == oldPayCode.paycodeCat) {
								ctrl.payCode.usedFor = oldPayCode.usedFor;
							} else {
								ctrl.payCode.usedFor = payCodeCatObj.usedFor;
							}
							setReconcileDisableFlag(payCodeCat);
							setExcludeDisableFlag(payCodeCat);
							seFeeCodeShowFlag(payCodeCat);
							seDynaParmShowOrHidden(payCodeCat);
							
							angular.forEach(crdrs, function(crdr, index1) {
								resetData(crdr, payCodeCatObj);
								ctrl.crdrChanged();
								ctrl[crdr + "DeliveryTypeOptions"].data = payCodeCatObj[crdr + "DeliveryTypeOptions"];
								//set Advice Data.
								seAdViceData(payCodeCatObj, crdr);
								ctrl[crdr +"DeliveryTypeChanged"] = function(value) {
									var crdrDeliveryType = ctrl.payCode[crdr +"DeliveryType"];
									angular.forEach(payCodeCatObj[crdr + "DeliveryTypes"], function(deliveryTypeObj, index) {
										var deliverTypeLabel = deliveryTypeObj.deliveryTypeDesc;
										deliverTypeLabel = firstStrToUpCase(deliverTypeLabel);
										ctrl[crdr + "DeliveryInfo" + deliverTypeLabel + "Flag"] = false;
										if(crdrDeliveryType == deliveryTypeObj.deliveryType) {
											ctrl[crdr + "DeliveryInfo" + deliverTypeLabel + "Flag"] = true;
										}
									});
								}
								//first income invoke first time
								ctrl[crdr +"DeliveryTypeChanged"]();
							});
						}
					});
				}
				ctrl.payCodeCatChanged();
				//reset payCode userFor
				if(oldPayCode.usedFor) {
					ctrl.payCode.usedFor = oldPayCode.usedFor;
				}
			}
		}
		function initPayCodeLookupData(ctrl) {
			var defer = $q.defer();
			dropDownDataOptions().then(function(response) {
				ctrl.usedForOptions = response.usedForOptions;
				ctrl.usedForOptions.hasEmptyOption = true;
				defer.resolve();
			}, angular.noop);
			return defer.promise;
		}
		return {
			initDropDownDataOptions : initDropDownDataOptions,
			dropDownDataOptions : dropDownDataOptions,
			initGeneral : initGeneral,
			initPayCodeLookupData: initPayCodeLookupData
		};
	}
})(angular);
